import { createFromIconfontCN } from '@ant-design/icons';
import { useEffect, useRef, useState } from 'react';
import BoardPanel from './components/Board';
import style from './index.less';
const IconFont = createFromIconfontCN({
  scriptUrl: '//at.alicdn.com/t/c/font_4525958_xrtglzzmvy.js',
});

const iconType = [
  'icon-drawboard',
  'icon-pen',
  'icon-eraser',
  'icon-delete',
  'icon-revert',
  'icon-recover',
];

const drawingBoardColor: string[] = [
  '#fff',
  '#f5222d',
  '#fa8c16',
  '#ffec3d',
  '#4096ff',
  '#73d13d',
  '#ff85c0',
  '#000',
];

const penBoardColor: string[] = [
  '#000',
  '#8b7191',
  '#a0d911',
  '#fffb8f',
  '#a8071a',
  '#ffbb96',
  '#5f88a6',
  '#389e0d',
  '#08979c',
  '#a34697',
  '#4096ff',
  '#fff',
];

let undoArr: (string | undefined)[] = [];
let redoArr: (string | undefined)[] = [];

const DrawingBoard: React.FC = () => {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const wrapperRef = useRef<HTMLDivElement>(null);
  const [panelColor, setPanelColor] = useState('#fff');
  const [select, setSelect] = useState('icon-drawboard');
  const [ctx, setCtx] = useState<CanvasRenderingContext2D | null>(null);
  const [cursor, setCursor] = useState('');
  const [penColor, setPenColor] = useState('#000');

  const [showBoardPanel, setShowBoardPanel] = useState(false);
  const [showPenPanel, setShowPenPanel] = useState(false);
  const [penSize, setPenSize] = useState(5);

  const selectRef = useRef(select);
  const penSizeRef = useRef(penSize)

  useEffect(()=>{
    penSizeRef.current = penSize
  })

  function onMouseMove(e: MouseEvent) {
    if (ctx) {
      if (selectRef.current === 'icon-pen') {
        ctx.lineTo(e.offsetX, e.offsetY);
        ctx.stroke();
      }
      if (selectRef.current === 'icon-eraser') {
        ctx.clearRect(e.offsetX - 10, e.offsetY - 10, 20, 20);
      }
    }
  }

  function onMouseUp() {
    canvasRef.current?.removeEventListener('mousemove', onMouseMove);
    // redoArr.push(canvasRef.current?.toDataURL())
  }

  function onMouseDown(e: MouseEvent) {
    if (ctx) {
      if (selectRef.current === 'icon-pen') {
        ctx.strokeStyle = penColor;
        ctx.lineWidth = penSizeRef.current;
        ctx.beginPath();

        undoArr.push(canvasRef.current?.toDataURL());
        ctx.moveTo(e.offsetX, e.offsetY);
        canvasRef.current?.addEventListener('mousemove', onMouseMove);
      } else if (selectRef.current === 'icon-eraser') {
        console.log('eraser');
      }
    }
  }

  function removeListener(node: HTMLCanvasElement) {
    node.removeEventListener('mousedown', onMouseDown);
    node.removeEventListener('mousemove', onMouseMove);
    node.removeEventListener('mouseup', onMouseUp);
  }

  useEffect(() => {
    if (ctx) {
      ctx.fillStyle = panelColor;
      ctx.fillRect(0, 0, canvasRef.current!.width, canvasRef.current!.height);
    }
  }, [panelColor, ctx]);

  useEffect(() => {
    if (canvasRef.current) {
      const ctx = canvasRef.current.getContext('2d')!;
      setCtx(ctx);
      canvasRef.current.width = wrapperRef.current!.clientWidth;
      canvasRef.current.height = wrapperRef.current!.clientHeight;
      // addListener(canvasRef.current)
      canvasRef.current.addEventListener('mousedown', onMouseDown);
      canvasRef.current.addEventListener('mouseup', onMouseUp);
      ctx.save();
    }
  }, [canvasRef.current]);

  useEffect(() => {
    selectRef.current = select;
  });

  function doRevert(type: string) {
    removeListener(canvasRef.current!);
    switch (type) {
      case 'icon-delete': {
        undoArr = [];
        redoArr = [];
        ctx?.clearRect(0, 0, canvasRef.current!.width, canvasRef.current!.height);
        break;
      }
      case 'icon-revert': {
        /**
         * 问题：画（最后一步） 撤销 恢复未能恢复到最后一步的状态
         * 解决: 撤销前，将当前状态保存进恢复栈里面
         */
        /**
         * 问题：撤销 撤销 撤销 恢复 再撤销 得按两次才能正确撤销
         * 解决：恢复前，将当前状态保存进撤销栈里面
         */
        if (undoArr.length > 0) {
          redoArr.push(canvasRef.current?.toDataURL());
          const url = undoArr.pop() as string;

          ctx?.clearRect(0, 0, canvasRef.current!.width, canvasRef.current!.height);

          let img = new Image();
          img.src = url;
          // ctx?.drawImage(img,0,0)
          img.onload = () => {
            ctx?.drawImage(img, 0, 0);
          };
          break;
        }
      }
      case 'icon-recover': {
        if (redoArr.length > 0) {
          undoArr.push(canvasRef.current?.toDataURL());
          const url = redoArr.pop() as string;
          // undoArr.push(url)
          ctx?.clearRect(0, 0, canvasRef.current!.width, canvasRef.current!.height);
          let img = new Image();
          img.src = url;
          img.onload = () => {
            ctx?.drawImage(img, 0, 0);
          };
        }
      }
    }
  }


  function doDraw(type: string) {
    switch (type) {
      case 'icon-drawboard': {
        // !showBoardPanel && showPenPanel &&  setShowPenPanel(false)
        if (!showBoardPanel && showPenPanel) {
          setShowPenPanel(false);
        }
        setShowBoardPanel(!showBoardPanel);
        setCursor('default');
        break;
      }
      case 'icon-pen': {
        canvasRef.current?.addEventListener('mousedown', onMouseDown);
        canvasRef.current?.addEventListener('mouseup', onMouseUp);
        if (!showPenPanel && showBoardPanel) {
          setShowBoardPanel(false);
        }
        setShowPenPanel(!showPenPanel);
        setCursor('crosshair');
        break;
      }
      case 'icon-eraser': {
        setCursor('');
        console.log(ctx, 'ctx');
        console.log(canvasRef, 'canvasRef');
        canvasRef.current?.addEventListener('mousedown', onMouseDown);
        canvasRef.current?.addEventListener('mouseup', onMouseUp);
        // canvasRef.current?.addEventListener('mousemove',onMouseMove)
        // setCursor('url(../../assets/erase.png) 0 0,auto')
        // 获取最新的值
        // handleEraser(type)
        break;
      }
    }
  }

  function onSelect(type: string) {
    canvasRef.current?.removeEventListener('mousedown', onMouseDown);
    canvasRef.current?.removeEventListener('mousemove', onMouseMove);
    canvasRef.current?.removeEventListener('mouseup', onMouseUp);

    if (['icon-drawboard', 'icon-pen', 'icon-eraser'].includes(type)) {
      setSelect(type);
      doDraw(type);
    } else {
      doRevert(type);
    }
  }

  return (
    <div ref={wrapperRef} className={style.wrapper}>
      <div className={style.tools}>
        <div className={style.inner}>
          <ul className={style.list}>
            {iconType.map((type, index) => {
              return (
                <li
                  className={`${style.item} ${
                    select === type &&
                    ((select === 'icon-drawboard' && showBoardPanel) || select !== 'icon-drawboard')
                      ? style.active
                      : null
                  } cardFlag`}
                  onClick={() => onSelect(type)}
                  key={index}
                >
                  <IconFont className={`${style.icon} cardFlag`} type={type}></IconFont>
                </li>
              );
            })}
          </ul>
          {showBoardPanel && (
            <BoardPanel
              color={panelColor}
              flag="board"
              colorArr={drawingBoardColor}
              setColor={setPanelColor}
              setShowPanel={setShowBoardPanel}
            ></BoardPanel>
          )}
          {showPenPanel && (
            <BoardPanel
              color={penColor}
              flag="pen"
              colorArr={penBoardColor}
              setColor={setPenColor}
              setShowPanel={setShowPenPanel}
              penSize={penSize}
              setPenSize={setPenSize}
            ></BoardPanel>
          )}
        </div>
      </div>
      <canvas
        className={style.canvas}
        ref={canvasRef}
        style={{
          cursor,
        }}
      ></canvas>
    </div>
  );
};
export default DrawingBoard;
